package com.card.service.manager;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.card.auth.TokenUtil;
import com.card.consts.ScoreSourceConsts;
import com.card.consts.SystemConsts;
import com.card.entity.manager.Address;
import com.card.entity.manager.User;
import com.card.entity.manager.UserGift;
import com.card.entity.manager.UserScore;
import com.card.entity.system.Customer;
import com.card.entity.system.Gift;
import com.card.repository.IAddressRepository;
import com.card.repository.ICustomerRepository;
import com.card.repository.IGiftRepository;
import com.card.repository.IUserGiftRepository;
import com.card.repository.IUserRepository;
import com.card.repository.IUserScoreRepository;
import com.card.result.Result;
import com.card.util.RandomCode;
import com.card.vo.ExchangeCode;
import com.card.vo.ExchangeScore;

/**
 * ClassName: UserService <br/>
 * Function: userService. <br/>
 * date: 2018年10月16日 下午2:53:25 <br/>
 * 
 * @author lishuai11
 * @version
 * @since JDK 1.8
 */
@Service("userService")
public class UserService {

	private static final Logger logger = LoggerFactory.getLogger(UserService.class);

	@Autowired
	private IUserRepository userRepository;

	@Autowired
	private IAddressRepository addressRepository;

	@Autowired
	private ICustomerRepository customerRepository;

	@Autowired
	private IUserGiftRepository userGiftRepository;

	@Autowired
	private IUserScoreRepository userScoreRepository;

	@Autowired
	private IGiftRepository giftRepository;

	public Result findByUserId(int userId) {
		try {
			return Result.success("成功", findOne(userId));
		} catch (Exception e) {
			logger.error("UserService.findByUserId()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	public Result updateUser(User user) {
		try {
			User dbUser = findOne(user.getUserId());
			if (dbUser == null) {
				return Result.fail(Result.CLIENT_ERROR, "用户不存在");
			}
			int gender = user.getGender();
			if (gender == SystemConsts.GENDER_MAN || gender == SystemConsts.GENDER_WOMAN
					|| gender == SystemConsts.GENDER_UNKNOW) {
				dbUser.setCity(user.getCity());
				dbUser.setGender(user.getGender());
				dbUser.setIcon(user.getIcon());
				dbUser.setNickName(user.getNickName());
				userRepository.save(dbUser);
				return Result.success("成功");
			} else {
				return Result.fail(Result.CLIENT_ERROR, "非法参数");
			}
		} catch (Exception e) {
			logger.error("UserService.updateUser()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	/**
	 * 
	 * myCode:(我得邀请码). <br/>
	 * 
	 * @author lishuai11
	 * @param userId
	 * @return
	 * @since JDK 1.8
	 */
	public Result myCode(int userId) {
		try {
			User user = findOne(userId);
			if (user == null) {
				return Result.fail(Result.CLIENT_ERROR, "用户不存在");
			}
			String code;
			if (StringUtils.isBlank(user.getInviteCode())) {
				do {
					code = RandomCode.randomCode();
				} while (findByInviteCode(code) != null);
				user.setInviteCode(code);
				user = userRepository.save(user);
			}
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("inviteCode", user.getInviteCode());
			return Result.success("成功", jsonObject);
		} catch (Exception e) {
			logger.error("UserService.myCode()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	@Transactional
	public Result exchangeGiftByCode(int userId, ExchangeCode exchangeCode) {
		try {
			if (!checkExchangeCode(exchangeCode.getExchangeCode())) {
				return Result.fail(Result.CLIENT_ERROR, "无效兑换码");
			}
			if (exchangeCodeIsUsed(exchangeCode.getExchangeCode())) {
				return Result.fail(Result.CLIENT_ERROR, "兑换码已使用");
			}
			synchronized (SystemConsts.CLASS_LOCK) {
				Gift gift = giftRepository.findOne(exchangeCode.getGiftId());
				if (gift == null) {
					return Result.fail(Result.CLIENT_ERROR, "礼物不存在");
				}
				if (gift.getNumber() < exchangeCode.getNumber()) {
					return Result.fail(Result.CLIENT_ERROR, "礼物库存不足");
				}
				Address address = findAddressOne(exchangeCode.getAddressId());
				if (address == null) {
					return Result.fail(Result.CLIENT_ERROR, "地址不存在");
				}
				UserGift userGift = new UserGift(userId, exchangeCode.getGiftId(), exchangeCode.getAddressId(),
						exchangeCode.getNumber(), exchangeCode.getExchangeCode());
				userGiftRepository.save(userGift);
				gift.setNumber(gift.getNumber() - exchangeCode.getNumber());
				giftRepository.save(gift);
				return Result.success("兑换成功");
			}
		} catch (Exception e) {
			logger.error("UserService.exchangeGiftByCode()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}

	}

	@Transactional
	public Result exchangeGiftByScore(int userId, ExchangeScore exchangeScore) {
		try {
			synchronized (SystemConsts.CLASS_LOCK) {
				Gift gift = giftRepository.findOne(exchangeScore.getGiftId());
				if (gift == null) {
					return Result.fail(Result.CLIENT_ERROR, "礼物不存在");
				}
				if (gift.getNumber() < exchangeScore.getNumber()) {
					return Result.fail(Result.CLIENT_ERROR, "礼物库存不足");
				}
				gift.setNumber(gift.getNumber() - exchangeScore.getNumber());
				giftRepository.save(gift);
				User user = findOne(userId);
				if (user == null) {
					return Result.fail(Result.CLIENT_ERROR, "用户不存在");
				}
				if (user.getTotalScore() < exchangeScore.getScore()) {
					return Result.fail(Result.CLIENT_ERROR, "用户积分不足");
				}
				int realScore = gift.getScore() * exchangeScore.getNumber();
				if (realScore > exchangeScore.getScore()) {
					return Result.fail(Result.CLIENT_ERROR,
							"兑换" + exchangeScore.getNumber() + "个礼物需要" + realScore + "积分");
				}
				Address address = findAddressOne(exchangeScore.getAddressId());
				if (address == null) {
					return Result.fail(Result.CLIENT_ERROR, "地址不存在");
				}
				UserGift userGift = new UserGift(userId, exchangeScore.getGiftId(), exchangeScore.getAddressId(),
						exchangeScore.getNumber());
				userGiftRepository.save(userGift);
				UserScore userScore = new UserScore(userId, ScoreSourceConsts.ACTIVITY_EXCHANGE,
						exchangeScore.getScore(), false);
				userScoreRepository.save(userScore);
				user.setTotalScore(user.getTotalScore() - exchangeScore.getScore());
				userRepository.save(user);
				return Result.success("兑换成功");
			}
		} catch (Exception e) {
			logger.error("UserService.exchangeGiftByScore()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	public Result myGifts(int userId, int pageNum, int pageSize) {
		try {
			pageNum = (pageNum - 1) * pageSize;
			List<UserGift> userGifts = findGiftsByUserId(pageNum, pageSize, userId);
			if (userGifts != null && !userGifts.isEmpty()) {
				Gift gift;
				for (UserGift userGift : userGifts) {
					gift = giftRepository.findOne(userGift.getGiftId());
					userGift.setGiftImage(gift.getGiftImage());
					userGift.setGiftName(gift.getGiftName());
				}
			}
			return Result.success("成功", userGifts);
		} catch (Exception e) {
			logger.error("UserService.exchangeGiftByScore()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	public Result scoreDetail(int userId, int pageNum, int pageSize) {
		try {
			pageNum = (pageNum - 1) * pageSize;
			return Result.success("成功", findUserScoreByUserId(pageNum, pageSize, userId));
		} catch (Exception e) {
			logger.error("UserService.scoreDetail()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	/**
	 * 
	 * addressList:(地址列表). <br/>
	 * 
	 * @author lishuai11
	 * @return
	 * @since JDK 1.8
	 */
	public Result addressList(int userId) {
		try {
			return Result.success("成功", findAddressByUserId(userId));
		} catch (Exception e) {
			logger.error("UserService.addressList()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	/**
	 * 
	 * addAddress:(添加地址). <br/>
	 * 
	 * @author lishuai11
	 * @param address
	 * @since JDK 1.8
	 */
	@Transactional
	public Result addAddress(Address address) {
		try {
			address = addressRepository.save(address);
			if (address.isSelect()) {
				List<Address> list = findAddressNotContainAddressId(address.getAddressId());
				if (list != null && !list.isEmpty()) {
					for (Address address2 : list) {
						address2.setSelect(false);
						addressRepository.save(address2);
					}
				}
			}
			return Result.success("成功");
		} catch (Exception e) {
			logger.error("UserService.addAddress()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	/**
	 * 
	 * updateAddress:(更新地址). <br/>
	 * 
	 * @author lishuai11
	 * @param address
	 * @since JDK 1.8
	 */
	@Transactional
	public Result updateAddress(Address address) {
		try {
			Address dbAddress = findAddressOne(address.getAddressId());
			if (dbAddress == null) {
				return Result.fail(Result.CLIENT_ERROR, "收货地址不存在");
			}
			dbAddress.setCity(address.getCity());
			dbAddress.setCode(address.getCode());
			dbAddress.setDetail(address.getDetail());
			dbAddress.setMobile(address.getMobile());
			dbAddress.setProvince(address.getProvince());
			dbAddress.setReceiveName(address.getReceiveName());
			dbAddress.setUnit(address.getUnit());
			dbAddress.setSelect(address.isSelect());
			dbAddress = addressRepository.save(dbAddress);
			if (dbAddress.isSelect()) {
				List<Address> list = findAddressNotContainAddressId(dbAddress.getAddressId());
				if (list != null && !list.isEmpty()) {
					for (Address address2 : list) {
						address2.setSelect(false);
						addressRepository.save(address2);
					}
				}
			}
			return Result.success("success");
		} catch (Exception e) {
			logger.error("UserService.updateAddress()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	/**
	 * 
	 * deleteAddress:(删除地址). <br/>
	 * 
	 * @author lishuai11
	 * @param addressId
	 * @return
	 * @since JDK 1.8
	 */
	public Result deleteAddress(int addressId) {
		try {
			Address address = findAddressOne(addressId);
			if (address == null) {
				return Result.fail(Result.CLIENT_ERROR, "收货地址不存在");
			}
			addressRepository.delete(addressId);
			return Result.success("删除成功");
		} catch (Exception e) {
			logger.error("UserService.deleteAddress()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	/**
	 * 
	 * deleteAllAddress:(清空地址). <br/>
	 * 
	 * @author lishuai11
	 * @param userId
	 * @return
	 * @since JDK 1.8
	 */
	public Result deleteAllAddress(int userId) {
		try {
			addressRepository.deleteByUserId(userId);
			return Result.success("已清空");
		} catch (Exception e) {
			logger.error("UserService.deleteAddress()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	/**
	 * 
	 * logout:(退出). <br/>
	 * 
	 * @author lishuai11
	 * @param token
	 * @return
	 * @since JDK 1.8
	 */
	public Result logout(String token) {
		try {
			TokenUtil.delToken(token);
			return Result.success("成功");
		} catch (Exception e) {
			logger.error("UserService.logout()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	private List<Address> findAddressByUserId(int userId) {
		return addressRepository.findByUserId(userId);
	}

	private Address findAddressOne(int addressId) {
		return addressRepository.findOne(addressId);
	}

	private List<Address> findAddressNotContainAddressId(int addressId) {
		return addressRepository.findAddressNotContainAddressId(addressId);
	}

	private User findOne(int userId) {
		return userRepository.findOne(userId);
	}

	private User findByInviteCode(String inviteCode) {
		List<User> list = userRepository.findByInviteCode(inviteCode);
		if (list != null && !list.isEmpty()) {
			return list.get(0);
		}
		return null;
	}

	private List<UserScore> findUserScoreByUserId(int pageNum, int pageSize, int userId) {
		return userScoreRepository.pageSearchByUserId(pageNum, pageSize, userId);
	}

	private List<UserGift> findGiftsByUserId(int pageNum, int pageSize, int userId) {
		return userGiftRepository.pageSearchByUserId(pageNum, pageSize, userId);
	}

	/**
	 * 
	 * checkExchangeCode:(这里用一句话描述这个方法的作用). <br/>
	 * 提供方式：两种 <br/>
	 * ①此处校验应该是提供接口进行校验 <br/>
	 * ②样本数据同步到系统内部表:SampleUser <br/>
	 * 检验方式<br/>
	 * ③电话号码前三位与电话号码后4位校验对比<br/>
	 * 
	 * @author lishuai11
	 * @param exchangeCode
	 * @return
	 * @since JDK 1.8
	 */
	private boolean checkExchangeCode(String exchangeCode) {
		if (exchangeCode != null && !exchangeCode.equals("")) {
			StringBuilder stringBuilder = new StringBuilder(exchangeCode);
			stringBuilder.replace(3, 7, "****");
			List<Customer> list = customerRepository.findByCustomeMobile(stringBuilder.toString());
			if (list != null && !list.isEmpty()) {
				return true;
			}
		}
		return false;
	}

	private boolean exchangeCodeIsUsed(String exchangeCode) {
		List<UserGift> userGifts = userGiftRepository.findByExchangeCode(exchangeCode);
		if (userGifts != null && !userGifts.isEmpty()) {
			return true;
		}
		return false;
	}

}
